package com.zy.example.hook;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * {@link BeanPostProcessor} 使用场景其实非常多，因为它可以获取正在初始化的{@link Bean}对象，然后可以对{@link Bean}
 * 对象做一些定制化的操作，如：判断该{@link Bean}是否为某个特定对象、获取{@link Bean}的注解元数据等。
 * postProcessBeforeInitialization在对象创建之后，afterPropertiesSet之前执行，
 * postProcessAfterInitialization在afterPropertiesSet之后执行
 *
 * {@link BeanFactoryPostProcessor}其提供了一个 postProcessBeanFactory方法，当所有的 BeanDefinition
 * 被加载时，该方法会被回调。
 *
 * @author zy
 * @since 2021/9/22
 */
@Component
@Slf4j
public class PostProcessorTest implements BeanPostProcessor, BeanFactoryPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("beanTest")) {
            log.info("PostProcessorTest：BeanTest对象创建之后，afterPropertiesSet之前执行");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (beanName.equals("beanTest")) {
            log.info("PostProcessorTest：afterPropertiesSet之后执行" + beanName);
        }
        return bean;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        log.info("PostProcessorTest：当所有的 BeanDefinition被加载时，该方法会被回调");
        String beanNames[] = beanFactory.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
            log.info(beanDefinition.toString());
        }
    }
}
